package tmt.usercenter.web.controller;

import com.tmt.datatable.model.FileInfo;
import com.tmt.fileservice.IFileService;
import com.tmt.helper.PackageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import tmt.usercenter.web.Application;
import tmt.usercenter.web.common.Const;
import tmt.usercenter.web.service.FilePropertyService;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLDecoder;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

/**
 * Created by ThreeManTeam on 2017/5/27.
 */
@Controller
@RequestMapping("/")
public class FileController extends BaseController {

    private static String ENTITY_BASE_PACKAGE_NAME = Application.class.getPackage().getName();

    @Autowired
    private FilePropertyService filePropertyService;

    @Autowired
    private IFileService fileService;

    @Autowired
    private ResourceLoader resourceLoader;

    /**
     * 所有/asset/img/下的图片，如果找不到则使用默认图片代替。
     * @param request
     * @param response
     * @param fileName
     */
    @ResponseBody
    @RequestMapping("/asset/img/{fileName}")
    public void loadFile(HttpServletRequest request, HttpServletResponse response,
                         @PathVariable("fileName") String fileName){
        try {
            fileName = URLDecoder.decode(fileName, "utf-8");
            String url = request.getRequestURI();
            String[] fileInfos = url.split(fileName);
            String fileSuffix = fileInfos[fileInfos.length - 1];
            String realPath = MessageFormat.format("{0}{1}{2}", Const.DEFAULT_IMG_CLASSPATH, fileName, fileSuffix);
            loadFile(realPath, response.getOutputStream());
        }catch (Exception ex){
            ex.printStackTrace();
        }
    }

    @ResponseBody
    @RequestMapping("/filestore/{basePath}/{clsName}/{id}/{propertyName}/{suffix}/{fileName}")
    public void loadFile(HttpServletRequest request, HttpServletResponse response,
                         @PathVariable("basePath") String basePath,
                         @PathVariable("clsName") String clsName,
                         @PathVariable("id") String id,
                         @PathVariable("propertyName") String propertyName,
                         @PathVariable("suffix") String suffix,
                         @PathVariable("fileName") String fileName) {
        response.setContentType("image/jpg");
        try {
            String fileUrl = URLDecoder.decode(request.getRequestURI(), "utf-8");
            OutputStream out = response.getOutputStream();
            try {
                fileService.loadByUrl(fileUrl, out);
                response.flushBuffer();
            } catch (Exception ex) {
                logger.debug(MessageFormat.format("访问图片{0}异常：{1}", fileUrl, ex.getMessage()));
                String realPath = MessageFormat.format("{0}{1}{2}_{3}{4}", Const.DEFAULT_IMG_CLASSPATH,
                        Const.DEFAULT_IMG_PREFIX, clsName, propertyName, Const.DEFAULT_IMG_SUFFIX);
                loadFile(realPath, out);
            }
        }catch (Exception ex){
            logger.debug(MessageFormat.format("-----response.getOutputStream()------", ex.getMessage()));
        }
    }

    @RequestMapping("/filestore/materials/{clsName}/{id}")
    public String displayFiles(@PathVariable("clsName") String clsName,
                               @PathVariable("id") Long id, Model model) {
        List<String> clsNameList = PackageHelper.getClassName(ENTITY_BASE_PACKAGE_NAME);
        Optional optional = clsNameList.stream().filter(x->x.endsWith("."+ clsName)).findFirst();
        if (optional.isPresent()) {
            try {
                String clazzName = optional.get().toString();
                clazzName = clazzName.substring(clazzName.indexOf(ENTITY_BASE_PACKAGE_NAME));
                Class<?> clazz = Class.forName(clazzName);
                List<FileInfo> fpList = filePropertyService.getFileInfo(clazz, id);
                model.addAttribute("materials", fpList);
            }catch (Exception ex){}
        }
        return "materials";
    }

    private void transferData(InputStream in, OutputStream out) throws IOException {
        byte[] bytes = new byte[1024];
        int len = -1;
        while ((len = in.read(bytes)) != -1) {
            out.write(bytes, 0, len);
        }
    }

    private void loadFile(String fileRealPath, OutputStream out){
        try {
            InputStream in = null;
            try {
                //直接加载
                in = resourceLoader.getResource(fileRealPath).getInputStream();
            }catch(Exception ex) {

                //加载img目录下的所有文件。
                Resource[] resources = ((AnnotationConfigEmbeddedWebApplicationContext) resourceLoader)
                        .getResources(Const.DEFAULT_IMG_CLASSPATH+"*.*");

                //异常后，尝试加载同名的不同类型的文件。
                try{
                    String[] infos = fileRealPath.split("/");
                    String fileName = infos[infos.length - 1].split("\\.")[0];
                    //尝试加载第一个同名的文件。
                    Optional<Resource> resource = Arrays.asList(resources).stream()
                            .filter(x->x.getFilename().toLowerCase().startsWith(fileName.toLowerCase()+".")).findFirst();
                    if (resource.isPresent()){
                        in = resource.get().getInputStream();
                    }
                }catch (Exception ex1) {
                }

                //仍然异常，则加载默认图片文件。
                try {
                    if (in == null) {
                        //尝试加载默认的图片文件。
                        Optional<Resource> resource = Arrays.asList(resources).stream()
                                .filter(x->x.getFilename().toLowerCase().startsWith( Const.DEFAULT_IMG_PREFIX + ".")).findFirst();
                        if (resource.isPresent()){
                            in = resource.get().getInputStream();
                        }
                    }
                }catch (Exception ex1){}
            }

            //输出数据
            transferData(in, out);
        }catch (Exception ex){
           // ex.printStackTrace();
        }
    }
}
